import re

r_integer = re.compile('^-?\d+$')
r_float = re.compile('^-?(\d*\.\d+|\d+\.\d*)$')
r_hex = re.compile('^-?0[xX][\dabcdefABCDEF]+$')
r_binary = re.compile('^-?[01_]+[bB]$')
r_id = re.compile(r'^[^\d\.][@$\w]*$')


def is_number(s: str) -> bool:
    return is_integer(s) or is_float(s) or is_hex(s) or is_binary(s)


def is_binary(s: str) -> bool:
    return bool(r_binary.match(s))


def is_hex(s: str) -> bool:
    return bool(r_hex.match(s))


def is_integer(s: str) -> bool:
    return bool(r_integer.match(s))


def is_float(s: str) -> bool:
    return bool(r_float.match(s))


def is_string(s: str) -> bool:
    if len(s) < 2:
        return False
    return s[0] == '"' and s[-1] == '"'


def match_id(s: str) -> bool:
    return bool(r_id.match(s))


def open_code_file(path: str) -> str:
    import codecs
    f = open(path, 'r', encoding='utf-8')
    content = f.read().replace(codecs.BOM_UTF8.decode('utf-8'), '')
    f.close()
    content += '\n'
    if content.startswith('{') and content.startswith('}'):
        return content
    return '{' + content + '}'
